/**
 * Copyright (C) 2002-2007 WUZEWEN. All rights reserved.
 * WUZEWEN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 * This software is the confidential and proprietary information of
 * WuZeven, Personal. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with WuZeven.
 */

package com.kingcore.pda.core.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.UnavailableException;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.struts.action.ActionServlet;

import com.kingcore.framework.context.ApplicationContext;
import com.kingcore.framework.jdbc.ConnectionManager;
import com.kingcore.pda.PdaContext;
import com.kingcore.pda.core.service.PdaServiceLocator;
import com.kingcore.pda.project.bean.ProjectBean;
import com.kingcore.pda.project.dao.ProjectDao;
import com.kingcore.pda.project.dao.impl.ProjectDaoImpl;


/**
 * <p>java类文件的说明...</p>
 * @author Zeven on 2007-12-4
 * @version	1.0
 * @see		Object#equals(java.lang.Object)
 * @see		Object#hashCode()
 * @see		HashMap
 * @since	JDK5
 */

public class PdaActionServlet extends ActionServlet {


	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private final static Logger log = Logger.getLogger(PdaActionServlet.class); //parent class has log object. which is 'org.apache.commons.logging.impl.Log4JLogger'.
	private static String Default_DataSource_Name = "main";
	private String System_RunMode_Val;
	private String System_Conf_Root;
    /**
     * 本方法是继承父类ActionServlet所有的初始化方法后再加入我们自己的处理
     * 
     * 待扩展。
     */
    public void init() throws ServletException {
    	
        // Wraps the entire initialization in a try/catch to better handle
        // unexpected exceptions and errors to provide better feedback
        // to the developer
    	log.info("begin init() ..."); 
        try {   	
        	super.init();
        	
        	initBaseConfig();
        	
	    	initLog4j( System_Conf_Root, System_RunMode_Val);
	    	
	    	initKingCoreFramework( System_Conf_Root );
	    	
	    	initSystemParameter();
	    	
	    	log.info("end init()");     

        } catch (UnavailableException ex) {
            throw ex;
        } catch (Throwable t) {

            // The follow error message is not retrieved from internal message
            // resources as they may not have been able to have been 
            // initialized
            log.error("Unable to initialize Struts ActionServlet due to an "
                + "unexpected exception or error thrown, so marking the "
                + "servlet as unavailable.  Most likely, this is due to an "
                + "incorrect or missing library dependency.", t);
            throw new UnavailableException(t.getMessage());
        }    
    }
    

	private void initBaseConfig() throws Exception {
    	String appServerRoot = this.getServletContext().getRealPath("");
		System_Conf_Root = appServerRoot+File.separator+"WEB-INF"+File.separator+"conf";
		String mainConfigFile = System_Conf_Root + File.separator+ "system.properties" ;
		InputStream is = new FileInputStream( mainConfigFile );
		Properties mainProps = new Properties();
		mainProps.load(is);
		String runModel = mainProps.getProperty("run-model", "prod"); 
		System_RunMode_Val = runModel;
	}


	private void initLog4j(String system_Conf_Root, String system_RunMode_Val) {
		String log4jConf = system_Conf_Root+File.separator
									+ system_RunMode_Val+File.separator
									+"log4j.properties";
		// initialize log4J
		System.out.println("runModel:"+System_RunMode_Val);

		try {
			InputStream inputStream = new FileInputStream(log4jConf);
			Properties props = new Properties();
			props.load(inputStream);
			PropertyConfigurator.configure(props);	
			log.info("init Log4j configuration successfully!");
			
		} catch (IOException e) {
			log.error(e);
			e.printStackTrace();
		}	
	}


	private void initKingCoreFramework(String system_Conf_Root) {
		//wzw:为每个项目创建项目文档目录，如果需要创建的话
    	/***********************************************************
    	 * initial kingcore framework.
    	 ***********************************************************/
    	ApplicationContext.getInstance().initContext(
    				ConnectionManager.getInstance(), 
    				system_Conf_Root, 
    				Default_DataSource_Name);
    	
    	//wzw: init for xxxServiceLocator
    	PdaServiceLocator.initApplicationContext(this.getServletContext());
    	
    	//wzw:系统在web服务器的context path, 主要是在jsp页面使用	    	
    	String contextPath= this.getServletContext().getInitParameter("contextPath");
    	this.getServletContext().setAttribute("contextPath", contextPath);
    	
	}


	private void initSystemParameter() { 
    	
		log.info("begin read path information from web.xml ...");
    	//-----------------------------------
    	Map map = null;
    	map = getPramasFromWebXml();
    	PdaContext.getSystemProperty().putAll( map );

		log.info("begin read path information from database ...");
    	map = getPropertiesFormDatabase();
    	PdaContext.getSystemProperty().putAll( map );
		List prjList = (List) map.get( PdaContext.Key_SysProjectsList);
		Map prj = null;
		String projectCode = null;
		String projectName = null;
		String appCode = null;
		String path = null;
		String folder = null;
		File file = null;
		Map<String,ProjectBean> projectMap = new HashMap<String,ProjectBean>();
		List<ProjectBean> projectList = new ArrayList<ProjectBean>();
		for (int i=0; i<prjList.size(); ) {  //i++
			prj = (Map) prjList.get(i); //projectCode, projectName
			projectCode = prj.get("projectcode")+"";
			projectName = prj.get("projectname")+"";
			appCode  = prj.get("appcode")+"";
			path=  prj.get("exppath")==null?"":prj.get("exppath").toString();
			log.debug("projectCode="+projectCode);
			path = path.trim();
			log.debug("projectCode="+projectCode + "  path="+path);
			if(path.endsWith("/")){
				path = path.substring(0, path.length()-1);
			}
			
			folder = path.substring(path.lastIndexOf("/")+1, path.length());
			log.debug("projectCode="+projectCode + "  path="+path + "  folder="+folder);
	    	String appServerRoot = this.getServletContext().getRealPath("");
	    	if (StringUtils.isNotBlank(folder)) {
				file = new File(appServerRoot + File.separator
						+ "pda_project_doc" + File.separator + folder);  
				//mod from “project” to pda_project_doc
				if(!file.exists()){ //如果文件夹不存在
					file.mkdirs(); 
				}
			}
	    	
			prj.put("foldername", folder);
			
			ProjectBean prjBean = new ProjectBean();
			prjBean.setId(prj.get("id")+"");
			prjBean.setProjectCode(projectCode);
			prjBean.setProjectName(projectName);
			
			prjBean.setAppCode(appCode);
			prjBean.setCompanyCode(prj.get("companycode")+"");
			prjBean.setCompanyName(prj.get("companyname")+"");
			
			prjBean.setPoolName(prj.get("poolname")+"");
			prjBean.setDbType(prj.get("dbtype")+""); 
			prjBean.setDbName(prj.get("dbname")+"");
			prjBean.setTableCondition(prj.get("tablecondition")+"");
			prjBean.setExpPath(prj.get("exppath")+"");
			prjBean.setTemplateCode(prj.get("templatecode")+""); 
			prjBean.setFileEncode(prj.get("fileencode")+"");   //wzw:需要纯小写
			prjBean.setTableModuleNameOffset( prj.get("tablemodulenameoffset")==null?1:Integer.parseInt(prj.get("tablemodulenameoffset")+"" ) );
			
			prjBean.setFolderName(folder);
			 
			projectMap.put(projectCode, prjBean);
			projectList.add(prjBean);
			i++;  // 最后才增加
		}
		PdaContext.setProjectMap(projectMap);
    	// -----------------------------------  更多参数放在servletContext
    	this.getServletContext().setAttribute(PdaContext.Key_SystemProperty,  PdaContext.getSystemProperty());
    	this.getServletContext().setAttribute(PdaContext.Key_ProjectList,  projectList ); //为了使用el标签递归,java后台不需要
    	
	}


	private Map getPramasFromWebXml() {

		Map map = new Hashtable();
    	//通过配置文件获取社区编号
    	String val = null;

    	// 绝对路径
    	val = this.getServletContext().getInitParameter( PdaContext.Key_OutputFilePath );
    	map.put( PdaContext.Key_OutputFilePath , val);
    	
    	// 相对路径
    	val = this.getServletContext().getInitParameter( PdaContext.Key_jstels_schema_file );
    	val = this.getServletContext().getRealPath(val);
    	System.out.println("real-="+val);
    	map.put( PdaContext.Key_jstels_schema_file , val);
    	 
    	return map;
		
	}


	private Map getPropertiesFormDatabase() {
 
		Map property = new Hashtable();
		
		ProjectDao pdd = new ProjectDaoImpl();
		List rsw = pdd.queryProjectList();

		property.put( PdaContext.Key_SysProjectsList, rsw);
		return property;    	
    	
	}


	/**
     * 
     * <p>确保文件夹存在，不存在则创建它。</p>
     * @author Zeven on 2007-11-26
     * @param strFile
     */
    private void checkFileExists(String val) throws Exception {
		File file = new File(val);
		if(!file.exists()){
			throw new Exception("系统运行需要的文件夹："+val+" 不存在，请创建或者重新配置。");
		}
		
	}
    
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
